package com.ibeeking.found.msg.rest.service.mpevent;

import com.ibeeking.found.common.entity.open.OpenAuthDTO;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.common.enums.mp.WxMpSourceTypeEnum;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.msg.rest.service.*;
import com.ibeeking.found.msg.service.common.bo.MpAutoMessageBO;
import com.ibeeking.found.msg.service.common.bo.WxMpFansBO;
import com.ibeeking.found.msg.service.common.dos.MpAutoMessageDO;
import com.ibeeking.found.msg.service.common.dos.WxMpFansDO;
import com.ibeeking.found.msg.service.common.param.WxMpAutoMsgParam;
import com.ibeeking.found.msg.service.common.query.CallBackQuery;
import com.ibeeking.nematos.constants.enums.LogClassifyEnum;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.date.DateUtil;

import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.builder.outxml.TextBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 关注事件处理
 *
 * @Author ibeeking
 */
@Component
public class SubscribeHandler  implements WxMpMessageHandler {
    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private IOpenService wxOpenServiceImpl;
    @Resource
    private IWxMpFansService mpFansServiceImpl;
    @Resource
    private IMpAutoMessageService mpAutoMessageServiceImpl;
    @Resource
    private IEventMsgService eventMsgServiceImpl;
    @Resource
    private IWxMpMsgService wxMsgServiceImpl;

    @Override
    public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
                                    Map<String, Object> context, WxMpService weixinService,
                                    WxSessionManager sessionManager) {
        WxMpUser userWxInfo = null;
        try {
            userWxInfo = weixinService.getUserService().userInfo(wxMessage.getFromUser(), null);
        } catch (WxErrorException e) {
            LogUtils.error(LogClassifyEnum.ERROR_LOG, "关注异常");
        }
        String teantId = UserUtils.getTenantId();
        if(StringUtils.isBlank(teantId)){
            throw new BusinessException("无法获取租户TenantId!");
        }
        String appId = weixinService.getWxMpConfigStorage().getAppId();
        Long tenantId = UserUtils.getTenantID();
        OpenAuthDTO wxOpenAuthDTO = wxOpenServiceImpl.queryWxOpenAuthByTenantIdAndAppId(tenantId, appId);
        if (userWxInfo != null) {
            WxMpFansBO wxMpFansBO = mpFansServiceImpl.queryByOpenId(userWxInfo.getOpenId());
            if (null == wxMpFansBO) {
                WxMpFansDO wxMpFansDO = new WxMpFansDO();
                setMpUserValue(userWxInfo, wxMpFansDO);
                //查询appId
                wxMpFansDO.setAppId(wxOpenAuthDTO.getAppId());
                mpFansServiceImpl.add(wxMpFansDO);
            } else {
                WxMpFansDO wxMpFansDO = new WxMpFansDO();
                setMpUserValue(userWxInfo, wxMpFansDO);
                wxMpFansDO.setId(wxMpFansBO.getId());
                wxMpFansDO.setSubscribeNum(wxMpFansBO.getSubscribeNum() + 1);
                mpFansServiceImpl.modifyInfo(wxMpFansDO);
            }

            //查询关注时回复消息
            MpAutoMessageDO mpAutoMessageDO = new MpAutoMessageDO();
            mpAutoMessageDO.setAppId(wxOpenAuthDTO.getAppId());
            mpAutoMessageDO.setAutoType(WxConsts.EventType.SUBSCRIBE);
            mpAutoMessageDO.setPublishStatus(PublishStatusEnum.ENABLE.getValue());
            List<MpAutoMessageBO> callBack = mpAutoMessageServiceImpl.queryByCondition(mpAutoMessageDO);

            if (!Collections3.isEmpty(callBack)) {
                CallBackQuery callBackQuery = new CallBackQuery();
                callBackQuery.setAppId(callBack.get(0).getAppId());
                callBackQuery.setSourceType(WxMpSourceTypeEnum.valueOf(callBack.get(0).getSourceType()));
                callBackQuery.setUnionKey(callBack.get(0).getUnionKey());
                WxMpXmlOutMessage out = eventMsgServiceImpl.callBackMsg(wxMessage, callBackQuery);
                record(wxMessage, callBackQuery.getAppId(), callBackQuery.getUnionKey(), out);
                return out;
            }
        }
        return new TextBuilder().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).content("关注成功").build();
    }

    public static void setMpUserValue(WxMpUser userWxInfo, WxMpFansDO wxMpFansDO) {
        wxMpFansDO.setSubscribe(userWxInfo.getSubscribe() ? 1 : 0);
        wxMpFansDO.setOpenId(userWxInfo.getOpenId());
        wxMpFansDO.setUnionId(StringUtils.isNotBlank(userWxInfo.getUnionId()) ? userWxInfo.getUnionId() : "");
        wxMpFansDO.setNickName(userWxInfo.getNickname());
//        wxMpFansDO.setSex(userWxInfo.getSex());
//        wxMpFansDO.setCountry(userWxInfo.getCountry());
//        wxMpFansDO.setProvince(userWxInfo.getProvince());
//        wxMpFansDO.setCity(userWxInfo.getCity());
        wxMpFansDO.setLanguage(userWxInfo.getLanguage());
        wxMpFansDO.setHeadImgurl(userWxInfo.getHeadImgUrl());
        wxMpFansDO.setSubscribeTime(DateUtil.longToLocalDateTime(userWxInfo.getSubscribeTime()));
        wxMpFansDO.setRemark(StringUtils.isNotBlank(userWxInfo.getRemark()) ? userWxInfo.getRemark() : "");
        Optional.ofNullable(userWxInfo.getGroupId()).ifPresent(wxMpFansDO::setGroupId);
        wxMpFansDO.setSubscribeScene(userWxInfo.getSubscribeScene());
        Optional.ofNullable(userWxInfo.getQrScene()).ifPresent(wxMpFansDO::setQrScene);
        Optional.ofNullable(userWxInfo.getQrSceneStr()).ifPresent(wxMpFansDO::setQrSceneStr);
    }

    private void record(WxMpXmlMessage wxMessage, String appId, String unionKey, WxMpXmlOutMessage out) {
        WxMpAutoMsgParam param = new WxMpAutoMsgParam();
        param.setAppId(appId);
        param.setOpenId(wxMessage.getFromUser());
        param.setRepType(wxMessage.getMsgType());
        param.setRepEvent(wxMessage.getEvent());
        param.setUnionKey(unionKey);
        param.setReturnType(out.getMsgType());
        param.setRepContent(wxMessage.getContent());
        wxMsgServiceImpl.add(param);
    }
}
